import { Context, Next } from "koa";
import { z, ZodSchema, ZodError } from "zod";

// 验证请求体数据
const validateBody = (schema: ZodSchema) => {
  return async (ctx: Context, next: Next) => {
    try {
      const validatedData = schema.parse((ctx.request as any).body);
      ctx.state.validatedBody = validatedData;
      await next();
    } catch (error) {
      handleValidationError(ctx, error, "请求体");
    }
  };
};

// 验证查询参数
const validateQuery = (schema: ZodSchema) => {
  return async (ctx: Context, next: Next) => {
    try {
      const validatedData = schema.parse(ctx.query);
      ctx.state.validatedQuery = validatedData;
      await next();
    } catch (error) {
      handleValidationError(ctx, error, "查询参数");
    }
  };
};

// 验证路由参数
const validateParams = (schema: ZodSchema) => {
  return async (ctx: Context, next: Next) => {
    try {
      const validatedData = schema.parse(ctx.params);
      ctx.state.validatedParams = validatedData;
      await next();
    } catch (error) {
      handleValidationError(ctx, error, "路由参数");
    }
  };
};

// 处理验证错误
const handleValidationError = (
  ctx: Context,
  error: unknown,
  paramType: string
) => {
  if (error instanceof ZodError) {
    ctx.status = 400;
    ctx.body = {
      code: 400,
      message: `${paramType}验证失败`,
      errors: error.errors.map((err: any) => ({
        field: err.path.join("."),
        message: err.message,
      })),
    };
    return;
  }

  // 其他错误
  ctx.status = 500;
  ctx.body = {
    code: 500,
    message: "服务器内部错误",
  };
};

export { validateBody, validateQuery, validateParams };
